
varying vec3 LightDirection;
varying vec3 EyeSpaceNormal;
varying vec4 LightDiffuseColor;
varying vec4 VertexColor;
varying vec2 fs_TexCoords;

// SHADOW
varying vec4 ShadowCoords;

// preferez une variable uniforme
// les objets ne pourront etre plus sombre que la valeur de ambient si ils sont eloignees de la light
const vec3 ambient = vec3(0.1, 0.1, 0.1);

uniform sampler2D Texture0;

//#define USE_SHADOW2D
// SHADOW
#ifndef USE_SHADOW2D
uniform sampler2D DepthTexture;
#else
uniform sampler2DShadow DepthTexture;
#endif

void main()
{	
	vec3 N = normalize(EyeSpaceNormal);
	vec3 L = normalize(LightDirection);

	float NdotL = max(0.0, dot(N, L));

	vec4 TexColor = texture2D(Texture0, fs_TexCoords);

	vec3 FinalLightColor = max(ambient, NdotL * VertexColor.rgb * LightDiffuseColor.rgb);
	
	// SHADOW	
#ifdef USE_SHADOW2D	 
	float shadowMask = shadow2DProj(DepthTexture, ShadowCoords).r;
	float shadowFactor = 1.0;
	// pas besoin de faire le test de comparaison des distances puisqu'il a deja ete fait par le hardware
	// on obtient donc une valeur binaire pour shadowMask
	if (ShadowCoords.w > 0.0)
	{
		shadowFactor = max(1.0, shadowMask + 0.5);
	}
#else
	vec4 shadowCoordsProj = ShadowCoords / ShadowCoords.w;
	float shadowDistance = texture2DProj(DepthTexture, shadowCoordsProj).r;
	// alternativement:
	//float shadowDistance = texture2D(DepthTexture, shadowCoordsProj.st).r;
	
	float shadowFactor = 1.0;
	float bias = 0.0;

	// le test suivant permet d'eviter les backprojections lorsque W est inferieur a 0
	if (ShadowCoords.w > 0.0)
	{
		// Selon le resultat de la comparaison entre la valeur stockee dans la shadow map et le Z du fragment
		// on va le considerer comme recevant l'ombre (0.5) ou non (1.0)
		shadowFactor = ((shadowDistance+bias) < shadowCoordsProj.z) ? 0.5 : 1.0;
	}
#endif
	gl_FragColor = vec4(shadowFactor * TexColor.rgb * FinalLightColor, TexColor.a * 1.0);
}